/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright @ Huawei Technologies Co., Ltd. 2024-2024. ALL rights reversed.
 */
#ifndef _LINUX_EULEROS_HUNGTASK_H
#define _LINUX_EULEROS_HUNGTASK_H


#include <linux/sched.h>
#include <linux/spinlock_types.h>

#ifdef CONFIG_EULEROS_HUNGTASK_DEBUG

#define HUNGTASK_LOCK_DEPTH  32

struct hungtask_control_ops {
	void (*add_hung_task)(struct task_struct *task, unsigned long timeout);
	void (*check_task_end)(bool full_check);
};

struct lock_info {
	void *lock_addr;
	unsigned long *lock_caller;
};

struct hungtask_info {
	struct lock_info locking_info;
	struct lock_info locked_info[HUNGTASK_LOCK_DEPTH];
	int locked_cnt;
};

extern spinlock_t hungtask_control_lock;
extern struct hungtask_control_ops *hungtask_control;

extern void register_hungtask_control(struct hungtask_control_ops *co);
extern void unregister_hungtask_control(struct hungtask_control_ops *co);

extern int hungtask_debug_enable;

extern void hungtask_lock_acquire(void *lock_addr, unsigned long *ip);
extern void hungtask_lock_acquire_release(void *lock_addr, struct task_struct *task);
extern void hungtask_lock_acquired(void *lock_addr, unsigned long *ip);
extern void hungtask_lock_acquired_release(void *lock_addr);

extern void hungtask_debug_info(struct task_struct *t, unsigned long timeout);
#else
static inline void hungtask_lock_acquire(void *lock_addr, unsigned long *ip) {};
static inline void hungtask_lock_acquire_release(void *lock_addr, struct task_struct *task) {};
static inline void hungtask_lock_acquired(void *lock_addr, unsigned long *ip) {};
static inline void hungtask_lock_acquired_release(void *lock_addr) {};

#endif
#endif /* _LINUX_EULEROS_HUNGTASK_H */

